package com.lz.autotest.project.testmanage.autoTest.service.thread;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: X
 * @date: Created in 2023/6/25 13:10
 * @Description:
 */
public class ThreadGroup implements ThreadGroupInterface{

    //运行状态
    private boolean running = false;

    //线程数量
    private int groupNumber;

    //存储线程对象
    private final ConcurrentHashMap<XtsThreadDetail, List<Thread>> allThreads = new ConcurrentHashMap<>();

    //根据需要创建不同线程
    private void startNewThread(XtsThreadDetail xtsThreadDetail){
        Thread thread = XtsThreadFactory.configure(xtsThreadDetail);
        registerThread(xtsThreadDetail, thread);
        thread.start();
    }

    protected XtsThreadDetail makeThread(String threadName, ThreadContext context) {
        return new XtsThreadDetail(threadName, context);
    }

    private void registerThread(XtsThreadDetail xtsThreadDetail, Thread thread) {
        if (allThreads.get(xtsThreadDetail) == null) {
            List<Thread> threads = new ArrayList<>();
            threads.add(thread);
            allThreads.put(xtsThreadDetail, threads);
        } else {
            allThreads.get(xtsThreadDetail).add(thread);
        }
    }

    @Override
    public void start(int groupNum, ThreadContext context) {
        this.running = true;
        this.groupNumber = groupNum;
        int numThreads = getNumThreads();
        if (!(numThreads > groupNum)) {
            XtsThreadDetail xtsThreadDetail = makeThread("",context);
            for (int threadNum = 0; running && threadNum < (groupNum - numThreads); threadNum++) {
                startNewThread(xtsThreadDetail);
            }
        }
    }

    @Override
    public boolean stopThread(String threadName, boolean now) {
        for (Map.Entry<XtsThreadDetail, List<Thread>> threadEntry : allThreads.entrySet()) {
            XtsThreadDetail xtsThreadDetail = threadEntry.getKey();
            if (xtsThreadDetail.getThreadName().equals(threadName)) {
                stopThread(xtsThreadDetail, threadEntry.getValue(), now);
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean verifyThreadsStopped() {
        boolean stoppedAll = true;
        if(stoppedAll) {
            for (List<Thread> value : allThreads.values()) {
                for (Thread thread : value) {
                    if(!verifyThreadStopped(thread)) {
                        return false;
                    }
                }
            }
            return true;
        } else {
            return false;
        }
    }

    private static boolean verifyThreadStopped(Thread Thread) {
        boolean stopped = true;
        if (Thread != null) {
            if (Thread.isAlive()) {
                stopped = false;
            }
        }
        return stopped;
    }

    @Override
    public void tellThreadsToStop() {
        tellThreadsToStop(true);
    }

    public void tellThreadsToStop(boolean now) {
        running = false;
        allThreads.forEach((key, value) ->  stopThread(key, value, now));
    }

    private static void stopThread(XtsThreadDetail xtsThreadDetail, List<Thread> jvmXtsThreads, boolean interrupt) {
        for (Thread thread : jvmXtsThreads) {
            if (interrupt && thread != null) { // Bug 49734
                thread.interrupt(); // also interrupt JVM thread
            }
        }
    }

    //获取线程数量
    public int getNumThreads() {
        return allThreads.keySet().size();
    }

}
